package pl.edu.pw.ee.buildcity.scheduler;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pl.edu.pw.ee.buildcity.scheduler.api.BuildCityScheduler;
import pl.edu.pw.ee.buildcity.services.BuildDefinitionService;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import static org.fest.assertions.Assertions.assertThat;
import static pl.edu.pw.ee.buildcity.scheduler.BuildCityJobDetail.DEFAULT_TRIGGERS_GROUP;
import static pl.edu.pw.ee.buildcity.scheduler.BuildCityJobDetail.TRIGGERS_PREFIX;

/**
 * @author mgrzechocinski
 * @since 2009-10-11
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:scheduler-context.xml", "classpath:test-context.xml"})
public class BuildCitySchedulerIntegrationTestCase {

	@Resource(name = "buildCityScheduler")
	private BuildCityScheduler buildCityScheduler;

	@Resource(name = "buildDefinitionService")
	private BuildDefinitionService buildDefinitionService;

	private Scheduler scheduler;

	@SuppressWarnings("unused")
	@PostConstruct
	private void setScheduler() {
		scheduler = ((BuildCitySchedulerImpl) buildCityScheduler).getScheduler();
	}

	@Test
	// reload scheduler
	@DirtiesContext
	public void shouldAddJob() {
		// Given
		BuildCityJobDetail jd = new BuildCityJobDetail("myTestJob");

		// When
		buildCityScheduler.save(jd);

		// Then
		BuildCityJobDetail storedJob = buildCityScheduler.getJobDetail("myTestJob");
		assertThat(storedJob).isNotNull();
		assertThat(storedJob.getName()).isEqualTo("myTestJob");
	}

	@Test
	@DirtiesContext
	public void shouldAddJobWithTrigger() throws SchedulerException {
		// Given
		BuildCityJobDetail jd = new BuildCityJobDetail("myTestJob").withCronTrigger("*/2 * * * * ?");

		// When
		buildCityScheduler.save(jd);

		// Then
		assertThat(scheduler.getTrigger(TRIGGERS_PREFIX + "myTestJob", DEFAULT_TRIGGERS_GROUP)).isNotNull();
	}

	@Test
	@DirtiesContext
	public void shouldCancelExistingTrigger() throws SchedulerException {
		// Given
		BuildCityJobDetail jd = new BuildCityJobDetail("myTestJob").withCronTrigger("*/2 * * * * ?");
		buildCityScheduler.save(jd);

		// When
		jd.cancelTrigger();
		buildCityScheduler.save(jd);

		// Then
		assertThat(scheduler.getTrigger(TRIGGERS_PREFIX + "myTestJob", DEFAULT_TRIGGERS_GROUP)).isNull();
	}

	@Test
	@DirtiesContext
	public void shouldAddTriggerToExistingJobDefinition() throws SchedulerException {
		// Given
		BuildCityJobDetail jd = new BuildCityJobDetail("myTestJob");
		buildCityScheduler.save(jd);

		// When
		jd.withCronTrigger("*/10 * * * * ?");
		buildCityScheduler.save(jd);

		// Then
		assertThat(scheduler.getTrigger(TRIGGERS_PREFIX + "myTestJob", DEFAULT_TRIGGERS_GROUP)).isNotNull();
	}
}
